1/30/91 BMPCLIP is an adaptation of the program BSCRLAPP.PAS, a demo program provided with Turbo Pascal for Windows(TPW). I modified it to add the ability to copy the visible area of the bitmap to the Win3 clipboard. Another member of the CIS TPW forum added the capability to display 256 color bitmaps. As a bitmap viewer, it is rather limited in features, but the source code is a good example of bitmap handling in TPW. Of course, you need TPW to compile the code. Files: BMPCLIP.EXE -compiled bitmap viewer BMPCLIP.PAS -TPW source code BMPCLIP.RES -Win3 resource file BMPCLIP.TXT -this text file If you are intrested in the code, here is the documentation I uploaded to the CIS TPW forum describing the copy method I added to the demo program: A few notes on the CMCopyBmp procedure........ This is a simple procedure that allows the user of a program that displays bitmaps to copy the entire visible area of the currently active window to the clipboard. I have found this procedure to work reliably with monochrome(2 color), VGA(16 color) and SVGA(256 color) bitmaps. Most Windows programs use rectangular banding, where the user presses and holds the left mouse button to drag a rectangle over the area to be copied, releases the button and chooses the Copy command from the Edit menu to paste the area to the clipboard. I was working on an MDI Bitmap\Text viewer(DTPBrowser, functional demo available free on Microsoft Windows Advanced Users Forum, full function version $29) and found this method of cutting and pasting to be awkward when working with several small bitmap windows-you had to do a lot of scrolling to get the area you wanted, then go through the whole banding procedure, open the edit menu and choose copy, etc. It seemed a lot simpler to just resize the window to show the desired area and choose copy. Since this procedure returns a value of type TMessage, it is also a simple matter to add code to copy the bitmap window simply by pressing a hotkey or even a mouse button, eliminating the need to open the Edit menu. You should be able to use this procedure with little or no modification in your programs. The code for this procedure is quite simple... There are a few preliminary statements that enable the main procedure: const -->declare return value for Copy command added to cm_Copy = 205; to File menu (see resource file BMPCLIP.RES) procedure CMCopyBmp(var Msg: TMessage); virtual cm_First + cm_Copy; ----> method declaration for Copy procedure EnableMenuItem(Attr.Menu, cm_Copy, mf_ByCommand or mf_Grayed); ----> disables Copy command on menu when no bitmap is loaded EnableMenuItem(Attr.Menu, cm_Copy, mf_ByCommand or mf_Enabled); ----->enables Copy command after bitmap is loaded And in the Copy procedure itself....... DC := GetDC(HWindow); gets the device context of the active window MemDC1 := CreateCompatibleDC(DC); opens a compatible memory DC for our new bitmap GetClientRect(HWindow, R); These three lines copy the coordinates NWidth := R.Right; ----------> of the active window to record R of type NHeight := R.Bottom; TRect from which we get the integers Right and Bottom that are the width and height of the active window. NewBmp := CreateCompatibleBitmap(DC, NWidth, NHeight); ---->creates bitmap OldBitmap1 := SelectObject(MemDC1, NewBmp); handle NewBmp and selects our DC into it. if NewBmp = 0 then If there is not enough begin ----->memory for the operation, MessageBox(HWindow, 'Unable to copy Bitmap', display error message, 'Error', mb_IconExclamation or mb_ok); get rid of associated data SelectObject(MemDC1, OldBitmap1); structures and terminate DeleteDC(MemDC1); procedure. ReleaseDC(HWindow,DC) end else begin OldCursor := SetCursor(LoadCursor(0, idc_Wait)); --> display hourglass cursor BitBlt(MemDC1, 0, 0, NWidth, NHeight, DC, 0, 0, --> copy pixel bits from current Mode); DC(DC) to new DC(MemDC1) OpenClipboard(HWindow); Opens and clears clipboard, EmptyClipboard; ---------> set data type to cf_Bitmap, get SetClipboardData(cf_Bitmap, NewBmp); bitmap handle, close clipboard. CloseClipboard; SetCursor(OldCursor); ----> Reset cursor to whatever it was before SelectObject(MemDC1, OldBitmap1); DeleteDC(MemDC1); -------> clean up the mess ReleaseDC(HWindow,DC) IMPORTANT: If you want to put in error handling routines in between the OpenClipboard and CloseClipboard statements, make sure they do not terminate the procedure before closing the clipboard, as this will disable it for the remainder of your windows session(I have run across one or two shareware image viewers that do this). Anyway, I know this procedure is crude, but it works in both standard and MDI applications. (If you are using it in an MDI app, be sure to call it from the child window you use to display bitmaps-The TDW manual says menu procedures in MDI apps must be called from the MDI "Frame" window, but the procedure won't work this way.) The industrious ones among you might add more sophisticated error checking and handling, or even banding(ugh!). I uploaded this as is to help those using TPW and ObjectWindows to write graphics applications because we often run into problems due to OWL's lack of advanced graphics handling methods, so maybe this will help a few of you. It goes without saying that those of you with more advanced knowledge of TPW programming(which is probably most of you) could find better ways to do this, and I would be quite intrested to see them. The sources for this code were two superb books on Windows programming: "Programming Windows" (2nd Ed.) by Charles Petzold and "Turbo Pascal for Windows 3.0 Programming" by Tom Swan. I also found the article "DDE and the Clipboard in Windows" by Ray Duncan in his Power Programming column (PC Magazine 5/14/91) to be quite helpful. Enjoy, Scott Hanrahan [70144, 3033]